package com.vroom;

import java.util.Set;

import com.vroom.R;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;


/**
 * An activity that enables picking a paired or discovered Bluetooth device.
 * This code is derived from http://programming-android.labs.oreilly.com/ch15.html
 * 
 * @author Neale Petrillo
 * @version 1, 3/4/2011
 */
public class DeviceListActivity extends Activity {
    private static final String TAG = "DeviceListActivity";
    private static final boolean D = true;
    
    // Return Intent extra
    public static String EXTRA_DEVICE_ADDRESS = "device_address";
    
    
    // Member fields
    private BluetoothAdapter mBtAdapter;
    private ArrayAdapter<String> mPairedDevicesArrayAdapter;
    private ArrayAdapter<String> mNewDevicesArrayAdapter;
    
    @Override
    protected void onCreate(Bundle savedInstanceState){
	super.onCreate(savedInstanceState);
	
	//Setup the window
	setContentView(R.layout.device_list);
	
	//Initialize the button to perform device discovery
	Button scanButton = (Button) findViewById(R.id.button_scan);
	scanButton.setOnClickListener(new OnClickListener() {
	    public void onClick(View v) {
		doDiscovery();
		v.setVisibility(View.GONE);
	    }
	});//End setOnClickListener
	
	//Initialize array adapters. 
	mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
	mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
	
	//Find and set up the ListView for paired devices 
	ListView pariedListView = (ListView) findViewById(R.id.paired_devices);
	pariedListView.setAdapter(mPairedDevicesArrayAdapter);
	pariedListView.setOnItemClickListener(mDeviceClickListener);
	
	//Find and set up the ListView for newly discovered devices
	ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);
	newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
	newDevicesListView.setOnItemClickListener(mDeviceClickListener);
	
	//Register for broadcasts when a device is discovered
	IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
	this.registerReceiver(mReceiver, filter);
	
	//Register for broadcasts when discovery has finished
	filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
	this.registerReceiver(mReceiver, filter);
	
	//Get the local Bluetooth adapter
	mBtAdapter = BluetoothAdapter.getDefaultAdapter();
	
	//Get a set of currently paired devices
	Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
	
	//If there are paired devices add each one to the ArrayAdapter
	if(pairedDevices.size() > 0){
	    findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
	    
	    for(BluetoothDevice device : pairedDevices){
		mPairedDevicesArrayAdapter.add(device.getName() + "/n" + device.getAddress());
	    }//End for
	} else {
	    String noDevices = getResources().getText(R.string.none_paired).toString();
	    mPairedDevicesArrayAdapter.add(noDevices);
	}//End if/else
    }//End onCreate
    
    @Override
    protected void onDestroy(){
	super.onDestroy();
	
	//Make sure discovery is off
	if(mBtAdapter != null){
	    mBtAdapter.cancelDiscovery();
	}//End if
	
	//Unregister broadcast listeners
	this.unregisterReceiver(mReceiver);
    }//End onDesstroy
    
    /**
     * Start device discovery with the BluetoothAdapter
     */
    private void doDiscovery() {
	if(D) Log.d(TAG, "doDiscovery");
	
	//Indicate scanning in the title
	setProgressBarIndeterminateVisibility(true);
	setTitle(R.string.scanning);
	
	//Turn on sub-title for new devices
	findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
	
	//If we're already discovering stop
	if(mBtAdapter.isDiscovering()){
	    mBtAdapter.cancelDiscovery();
	}//End if
	
	//Request discover from BluetoothAdapter
	mBtAdapter.startDiscovery();
    }//End doDiscovery
    
    /**
     * The on-click listener for all devices in the ListViews
     */
    private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {
	public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3){
	    //Cancel discovery because it's costly and we're about to connect
	    mBtAdapter.cancelDiscovery();
	    
	    //Get MAC address
	    String info = ((TextView) v).getText().toString();
	    String address = info.substring(info.length() - 17);
	    
	    //Create the result Intent and include the MAC address
	    Intent intent = new Intent();
	    intent.putExtra(EXTRA_DEVICE_ADDRESS, address);
	    
	    //Set result and finish this Activity
	    setResult(Activity.RESULT_OK, intent);
	    finish();
	}//End onItemClick
    };//End mDeviceClickListener
    
    /**
     * The BroadcastReceiver that listens for discovered devices and changes the title when discovery is finished
     */
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
	@Override
	public void onReceive(Context context, Intent intent){
	    String action = intent.getAction();
	    
	    //When discovery finds a device
	    if(BluetoothDevice.ACTION_FOUND.equals(action)){
		//Get the BluetoothDevice object from the Intent
		BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
		
		//If it's already paired, skip it, because it's been listed already
		if(device.getBondState() != BluetoothDevice.BOND_BONDED){
		    mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
		} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
		    setProgressBarIndeterminateVisibility(false);
		    setTitle(R.string.select_device);
		    if(mNewDevicesArrayAdapter.getCount() == 0){
			String noDevices = getResources().getText(R.string.none_found).toString();
			mNewDevicesArrayAdapter.add(noDevices);
		    }//End if
		}//End if/else
	    }//End if
	}//End onReceive
    };//End BroadcastReceiver 
}//End DeviceListActivity
